#-*- coding: utf-8 -*-
#===============================================================================
# IMPORTS
#===============================================================================
from __future__ import unicode_literals

import traceback
import urllib2

from dateutil import parser
from django.db import models
from django.utils.timezone import utc
from mptt.fields import TreeForeignKey
from mptt.models import MPTTModel, TreeForeignKey

import datetime as DT
import xml.etree.ElementTree as ET


# Create your models here.
#===============================================================================
# MODELS
#===============================================================================
#===============================================================================
# 1) Api Account Management
#===============================================================================
# rationnaliser la gestion des API =>  1) account corpo => Create account => enregistré => crée les urls liés 
# et link avec la/les fonctions de refresh des api 
#le parser change sa manière de trier en fonction de l'api name (Asset List, ....)
#Lier ApiAccount avec Api (urls en fait) One to Many
#modele qui definit un api account
#===============================================================================
# MOVING IN SCM_AUTH!
#===============================================================================
class ApiAccount(models.Model):
    #add auto increment
    #accountID = models.BigIntegerField(primary_key = True)
    accountID = models.AutoField(primary_key = True)
    #free title for the user / unique Name => to check if not all ready exists in db / at.save()
    accountName = models.CharField(max_length=200)
    #corp or perso / ? => check Primary account need to be corp api key / at.save()
    accountType = models.CharField(max_length=200)
    keyID = models.IntegerField()
    vCode = models.CharField(max_length=400)
    
    def __unicode__(self):
        return self.accountName

    #fonction refresh all url of the apiAccount
    
    #fonction create_apiAccount

#===============================================================================
# #TO ERASE AND REFACTOR ! => API urls in code
#===============================================================================
#Noms des api et leur url perso pour construction de leur url finale
#base generale pour config => une fois setup NO MODIFY
class ApiNames(models.Model):
    apiName = models.CharField(primary_key=True,max_length=200)
    urlBase = models.CharField(max_length=200)
    urlRadical = models.CharField(max_length=200)
    fileName = models.CharField(max_length=300, null=True)
    filePath = models.FilePathField(null = True)

    def __unicode__(self):
        return self.apiName
    
#===============================================================================
# #TO REFACTOR ! => API urls in code
#===============================================================================
#modele qui definit un type d'api avec son url (est lie a un account)
class Api(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    apiName = models.ForeignKey(ApiNames)
    currentTime = models.DateTimeField(null=True)
    cachedUntil = models.DateTimeField(null=True)
    apiStatus = models.CharField(null=True, max_length=200)
    #A mettre dans le parser!
    apiUrl = models.URLField(null = True)
    
#     objects = ApiManager()
    
    def __unicode__(self):
        return self.apiName

#===============================================================================
# TO DO ???
#===============================================================================
#Creer model Corporation => découle d'un ApiAccount et relie les autres modèles ?   
#Pour l'instant lié via ApiAccount
 
 
 

#===========================================================================


#A DEPLACER DANS APIPARSER ?
#a ammeliorer pour definir le nom de l'api
#fonction pour rafraichir un seul url spécifique
def refreshStatus(self, cachedUntil):
    #aware time zone support (à voir si implémentation nécessaire) => settings USE_TZE = TRUE / app : pytz ?? => FAQ TZ
    #now = DT.datetime.utcnow().replace(tzinfo=utc)
    now = DT.datetime.now()
    if cachedUntil > now:
        status = 'up to date'
    else:
        status = 'cache expired'
    return status
    

#===============================================================================
# FOR FURTHER IMPLEMENTATION
#===============================================================================

#fonction/model pour les producteurs => gestion des producteurs
#récup character skills...etc ?
# class producer(models.Model):
#     charID = models.BigIntegerField(primary_key = True)
#     #links to api key perso
# 
# 
#     objects = ApiManager()
#     
#     def __unicode__(self):
#         return self.charID


#===============================================================================
# 2) API Data models (Asset List, Wallet Transactions...)
#===============================================================================

# parse xml au 1er niveau : result, puis après 1 rowset => chararcters:
#  <key accessMask="66838191" type="Corporation" expires="">
#        <rowset name="characters" key="characterID" columns="characterID,characterName,corporationID,corporationName">
#          <row characterID="1908436352" characterName="Gor Han" corporationID="1692069636" corporationName="Positronics Entreprises"/>
#        </rowset>
#      </key>
#modele des infos de l'api
class ApiInfo(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    accessMask = models.IntegerField()
    apiType = models.CharField(max_length=200)
    keyExpire = models.CharField(max_length=200)
    characterID = models.IntegerField()
    characterName = models.CharField(max_length=200)
    corporationID = models.IntegerField()
    corporationName = models.CharField(max_length=200)
     
    def __unicode__(self):
        return self.apiType

#modele pour la CorpSheet details
class CorpSheet(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    corporationID = models.IntegerField()
    corporationName = models.CharField(max_length=200)
    corpTicket = models.CharField(max_length=200)
    ceoID = models.IntegerField()
    ceoName = models.CharField(max_length=200)
    stationID = models.IntegerField()
    stationName = models.CharField(max_length=200)
    corpDescription = models.CharField(max_length=800)
    corpUrl = models.URLField()
    allianceID = models.IntegerField()
    factionID = models.IntegerField()
    corpTaxe = models.FloatField()
    memberCount = models.IntegerField()
    memberLimit = models.IntegerField()
    shares = models.IntegerField()
    #divisions 
    divAccountKey1000 = models.CharField(max_length=200)
    divAccountKey1001 = models.CharField(max_length=200)
    divAccountKey1002 = models.CharField(max_length=200)
    divAccountKey1003 = models.CharField(max_length=200)
    divAccountKey1004 = models.CharField(max_length=200)
    divAccountKey1005 = models.CharField(max_length=200)
    divAccountKey1006 = models.CharField(max_length=200)
    #walletDivisions
    walletAccountKey1000 = models.CharField(max_length=200)
    walletAccountKey1001 = models.CharField(max_length=200)
    walletAccountKey1002 = models.CharField(max_length=200)
    walletAccountKey1003 = models.CharField(max_length=200)
    walletAccountKey1004 = models.CharField(max_length=200)
    walletAccountKey1005 = models.CharField(max_length=200)
    walletAccountKey1006 = models.CharField(max_length=200)
    #logo infos
    graphicID = models.IntegerField()
    shape1 = models.IntegerField()
    shape2 = models.IntegerField()
    shape3 = models.IntegerField()
    color1 = models.IntegerField()
    color2 = models.IntegerField()
    color3 = models.IntegerField()
    
    def __unicode__(self):
        return self.corporationID

class AccountBalance(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    walletAccountKey1000 = models.FloatField()
    walletAccountKey1001 = models.FloatField()
    walletAccountKey1002 = models.FloatField() 
    walletAccountKey1003 = models.FloatField()
    walletAccountKey1004 = models.FloatField()
    walletAccountKey1005 = models.FloatField()
    walletAccountKey1006 = models.FloatField()

    def __unicode__(self):
        return self.walletAccountKey1000

class MarketOrders(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    orderID = models.BigIntegerField(primary_key=True)
    charID = models.IntegerField(null=False)
    stationID = models.IntegerField()
    volEntered = models.IntegerField()
    volRemaining = models.IntegerField()
    minVolume = models.IntegerField()
    orderState = models.IntegerField()
    typeID = models.IntegerField()
    range = models.IntegerField()
    accountKey = models.IntegerField()
    duration = models.IntegerField()
    escrow = models.FloatField()
    price = models.FloatField()
    bid = models.FloatField()
    issued = models.DateTimeField()

    def __unicode__(self):
        return self.walletAccountKey1000
    
    
#modele des transactions du wallet
class WalletTransaction(models.Model):
    #<rowset name="transactions" key="transactionID" columns="transactionDateTime,transactionID,quantity,typeName,typeID,price,clientID,
    #clientName,characterID,characterName,stationID,stationName,transactionType,transactionFor,journalTransactionID,clientTypeID">
    accountID = models.ForeignKey(ApiAccount)
    transactionID = models.BigIntegerField(primary_key= True)
    transactionDateTime = models.DateTimeField()
    transactionType = models.CharField(max_length=200)
    transactionFor = models.CharField(max_length=200)
    journalTransactionID = models.BigIntegerField()
    typeID = models.IntegerField()
    typeName = models.CharField(max_length=200)
    quantity = models.IntegerField()
    price = models.FloatField()
    clientID = models.IntegerField()
    clientName = models.CharField(max_length=200)
    characterID = models.IntegerField()
    characterName = models.CharField(max_length=200)
    stationID = models.IntegerField()
    stationName = models.CharField(max_length=200)
    
    
    clientTypeID = models.IntegerField()
    
    def __unicode__(self):
        return self.transactionID
    
#modele pour les wallet entries
class WalletJournal(models.Model):
    #<rowset name="entries" key="refID" columns="date,refID,refTypeID,ownerName1,ownerID1,
    #ownerName2,ownerID2,argName1,argID1,amount,balance,reason,owner1TypeID,owner2TypeID">
    accountID = models.ForeignKey(ApiAccount)
    refID = models.BigIntegerField(primary_key=True)
    date = models.DateTimeField()
    refTypeID = models.BigIntegerField()
    ownerName1 = models.CharField(max_length=200)
    ownerID1 = models.BigIntegerField()
    ownerName2 = models.CharField(max_length=200)
    ownerID2 = models.BigIntegerField()
    argName1 = models.CharField(max_length=400)
    argID1 = models.IntegerField()
    amount =  models.FloatField()
    balance = models.FloatField()
    reason = models.CharField(max_length=400)
    owner1TypeID = models.IntegerField()
    owner2TypeID = models.IntegerField()
    
    def __unicode__(self):
        return self.transactionID
 
#modele des industry jobs
class IndustryJob(models.Model):
    #<rowset name="jobs" key="jobID" columns="jobID,assemblyLineID,containerID,installedItemID,installedItemLocationID,
    #installedItemQuantity,installedItemProductivityLevel,installedItemMaterialLevel,installedItemLicensedProductionRunsRemaining,
    #outputLocationID,installerID,runs,licensedProductionRuns,installedInSolarSystemID,containerLocationID,materialMultiplier,
    #charMaterialMultiplier,timeMultiplier,charTimeMultiplier,installedItemTypeID,outputTypeID,containerTypeID,installedItemCopy,
    #completed,completedSuccessfully,installedItemFlag,outputFlag,activityID,completedStatus,installTime,beginProductionTime,endProductionTime,
    #pauseProductionTime">
    #AHAHAHAHA!!!! PUTAIN ! Y EN A ASSEZ DES CHAMPS ICI !
    accountID = models.ForeignKey(ApiAccount)
    jobID = models.BigIntegerField(primary_key=True)
    assemblyLineID = models.BigIntegerField()
    containerID = models.BigIntegerField()
    installedItemID = models.BigIntegerField()
    installedItemLocationID = models.BigIntegerField()
    installedItemQuantity = models.IntegerField()
    installedItemProductivityLevel = models.IntegerField()
    installedItemMaterialLevel = models.IntegerField()
    installedItemLicensedProductionRunsRemaining = models.IntegerField()
    outputLocationID = models.BigIntegerField()
    installerID = models.IntegerField()
    runs = models.IntegerField()
    licensedProductionRuns = models.IntegerField()
    installedInSolarSystemID = models.IntegerField()
    containerLocationID = models.IntegerField()
    materialMultiplier = models.FloatField()
    charMaterialMultiplier = models.FloatField()
    timeMultiplier = models.FloatField()
    charTimeMultiplier = models.FloatField()
    installedItemTypeID = models.IntegerField()
    outputTypeID = models.IntegerField()
    containerTypeID = models.IntegerField()
    installedItemCopy = models.IntegerField()
    #check si ok avec boolean => sinon integer
    completed = models.BooleanField()
    completedSuccessfully = models.BooleanField()
    installedItemFlag = models.IntegerField()
    outputFlag = models.IntegerField()
    activityID = models.IntegerField()
    completedStatus = models.IntegerField()
    installTime = models.DateTimeField()
    beginProductionTime = models.DateTimeField()
    endProductionTime = models.DateTimeField()    
    pauseProductionTime = models.DateTimeField()

    def __unicode__(self):
        return self.status
    
class PosList(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    itemID = models.BigIntegerField(primary_key=True)
    typeID = models.IntegerField()
    locationID = models.IntegerField()
    moonID = models.IntegerField()
    state = models.IntegerField()
    stateTimestamp = models.DateTimeField()
    onlineTimestamp = models.DateTimeField()
    standingOwnerID = models.BigIntegerField()
       
    def __unicode__(self):
        return self.accountID
        
class PosDetail(models.Model):
    accountID = models.ForeignKey(ApiAccount)
    itemID = models.ForeignKey(PosList)
    stateTimestamp = models.DateTimeField()
    onlineTimestamp = models.DateTimeField()
    state = models.IntegerField()
    usageFlags = models.IntegerField()
    delployFlags = models.IntegerField()
    allowCorpMembers = models.IntegerField()
    allowAllyMembers = models.IntegerField()
    useStandingsFrom = models.IntegerField()
    onStandingDrop = models.FloatField()
    onStatusDrop_enabled = models.IntegerField()
    onStatusDrop_standing = models.FloatField()
    onAggression = models.IntegerField()
    onCorpWar = models.IntegerField()
    fuel_1_ID = models.IntegerField()
    fuel_2_ID = models.IntegerField()
    fuel_3_ID = models.IntegerField()
    fuel_1_qty = models.IntegerField()
    fuel_2_qty = models.IntegerField()
    fuel_3_qty= models.IntegerField()
        
    def __unicode__(self):
        return self.accountID
     
     
# modele pour gerer les assets
# class Asset(models.Model):

class Asset(MPTTModel):
    accountID = models.ForeignKey(ApiAccount)
    itemID = models.BigIntegerField(primary_key=True)
    #parentID = TreeForeignKey('self', null=True, blank=False, related_name='children', db_index=True)#, db_column='parentID_id')
    parentID = models.ForeignKey('self', null=True, blank=False, related_name='children', db_index=True)#, db_column='parentID_id')
    parentName = models.CharField(max_length=200, null=True)
    #parentID = models.BigIntegerField(null=True)
    #itemName = models.CharField(max_length=200)
    locationID = models.IntegerField(null=True)
    locationStation = models.CharField(max_length=200, null=True)
    locationName = models.CharField(max_length=200, null=True)
    typeID = models.IntegerField()
    typeName = models.CharField(max_length=200, null=True)
    quantity = models.IntegerField()
    flag = models.IntegerField(null=True)
    flagName = models.CharField(max_length=200, null=True)
    flagText = models.CharField(max_length=200, null=True)
    singleton = models.IntegerField()
    rawQuantity = models.IntegerField(null=True)
    itemPrice = models.BigIntegerField(null=True)
     
    class MPTTMeta:
        order_insertion_by = ['itemID']
        parent_attr = 'parentID'
     
#     class Meta:
#         app_label = 'assetParser'
     
    def __unicode__(self):
        return str(self.itemID)